function ListNode () {
  const Node = function(element) {
    this.element = element
    this.next = null
  }

  let length = 0
  let head = null

  // 插入一个元素
  this.append = function(element) {
    let node = new Node(element),
      current;
    if (head == null) {
      head = node
    } else {
      current = head;
      while (current.next) {
        current = current.next
      }
      current.next = node
    }
    length++
  }

  // 向列表的指定位置插入一个新的项
  this.insert = function(position, element) {
    if (position >= 0 && position <= length) {
      let node = new Node(element),
        current = head,
        previous,
        index = 0;
      if (position === 0) {
        head = node
      } else {
        while (index++ < position) {
          previous = current
          current = current.next
        }
        node.next = current
        previous.next = node
      }
      length++
      return true
    } else {
      return false
    }
  }

  // 从列表特定位置移除一项
  this.removeAt = function(position) {
    if (position > -1 && position < length) {
      let current = head,
        previous,
        index = 0
      if (position === 0) {
        head = current.next
      } else {
        while (index++ < position) {
          previous = current;
          current = current.next
        }
        previous.next = current.next
      }
      length--
      return current.element
    } else {
      return false
    }
  }

  // 返回元素在列表中的索引, 如果列表中不存在返回 -1
  this.indexOf = function(element) {
    let current = head,
      index = 0
    while (current) {
      if (element === current.element) {
        return index
      }
      index++
      current = current.next
    }
    return -1
  }

  this.getIndex = function(position) {
    if (position > -1 && position <= length) {
      if (position === 0) {
        return head
      } else {
        let current = head,
          index = 0
        while(index++ !== position) {
          current = current.next
        }
        return current
      }
    } else {
      return null
    }
  }

  this.removeAt = function(element) {
    let index = this.indexOf(element)
    return this.removeAt(index)
  }

  this.isEmpty = function() {
    return length === 0
  }

  this.size = function() {
    return length
  }

  this.getHead = function() {
    return head
  }

  this.toString = function() {
    let current = head,
      string = ''
    while (current) {
      string += current.element + (current.next ? 'n' : '')
      current = current.next
    }
    return string
  }
}

window.ListNode = ListNode